package com.hollycrm.unicom.security.hibernate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;

import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.HibernateTemplate;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;

import com.hollycrm.springframework.factory.DefaultBeanFactory;
import com.hollycrm.springframework.util.StringUtils;
import com.hollycrm.unicom.logsupport.LogonLog;
import com.hollycrm.unicom.security.AuthManager;
import com.hollycrm.unicom.security.AuthToken;
import com.hollycrm.unicom.usersupport.Department;
import com.hollycrm.unicom.usersupport.Right;
import com.hollycrm.unicom.usersupport.Role;
import com.hollycrm.unicom.usersupport.Skill;
import com.hollycrm.unicom.usersupport.User;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class HibernateAuthManager
    extends HibernateDaoSupport
    implements AuthManager {

    /**
     * getAuthToken
     *
     * @param token String
     * @return AuthToken
     */
    public AuthToken getAuthToken(final String token) {
        HibernateTemplate ht = getHibernateTemplate();
        return (AuthToken) ht.execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @return Object
             * @throws HibernateException
             */
            public Object doInHibernate(Session session) throws HibernateException {
                AuthToken authToken = null;
                List userCodeList = session.find("select log.userCode from log in " +
                                                 LogonLog.class + " where log.logonID = ?",
                                                 token, Hibernate.STRING);
                String userCode = null;
                if (!userCodeList.isEmpty()) {
                    userCode = (String) userCodeList.get(0);
                }
                if (userCode != null) {
                    List userList = session.find("from u in " +
                                                 User.class +
                                                 " where u.userCode = ?",
                                                 userCode, Hibernate.STRING);
                    if (!userList.isEmpty()) {
                        authToken = (AuthToken) DefaultBeanFactory.getBean(
                            AuthToken.BEAN_ID);
                        buildAuthToken(authToken, (User) userList.get(0));
                    }
                }
                return authToken;
            }

        });
    }

    /**
     * getAuthToken
     *
     * @param userCode String
     * @param password String
     * @return AuthToken
     */
    public AuthToken getAuthToken(final String userCode, final String password) {
        HibernateTemplate ht = getHibernateTemplate();
        return (AuthToken) ht.execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @return Object
             * @throws HibernateException
             */
            public Object doInHibernate(Session session) throws
                HibernateException {
                AuthToken authToken = null;
                List userList = session.find("from u in " +
                                             User.class +
                                             " where u.userCode = ?", userCode,
                                             Hibernate.STRING);

                if (!userList.isEmpty()) {
                    User user = (User) userList.get(0);
                    if (password != null &&
                        password.equals(StringUtils.trim(user.getPassword()))) {
                        authToken = (AuthToken) DefaultBeanFactory.getBean(
                            AuthToken.BEAN_ID);
                        buildAuthToken(authToken, user);
                    }
                }
                return authToken;
            }

        });
    }

    /**
     * buildAuthToken
     * @param authToken AuthToken
     * @param user User
     */
    public void buildAuthToken(AuthToken authToken, User user) {
        authToken.setUserID(user.getUserID());
        authToken.setUserCode(new String(user.getUserCode()));
        authToken.setUserName(user.getUserName());
        authToken.setDeptID(user.getDepartment().getDeptID());
        authToken.setAllRights(getAllRights(user));
        authToken.setAllSkills(getAllSkills(user));
        authToken.setAttribute("vestAreaID", user.getVestAreaID());
        authToken.setAttribute("mobilePhone", user.getMobilePhone());
        authToken.setAttribute("email", user.getEmail());
        authToken.setAttribute("deptAncestors", getDeptAncestors(user.getDepartment()));
    }

    /**
	 * @param department
	 * @return
	 */
	private List getDeptAncestors(Department department) {
		List ancestors = new ArrayList();
		getDeptAncestors(department, ancestors);
		return ancestors;
	}

	/**
	 * @param department
	 * @param ancestors
	 */
	private void getDeptAncestors(Department department, List ancestors) {
		if (department != null && !"0".equals(department.getDeptID())) {
			getDeptAncestors(department.getParent(), ancestors);
			ancestors.add(department.getDeptID());
		}
	}

	/**
     * getAllSkills
     *
     * @param user User
     * @return Collection
     */
    private Collection getAllSkills(User user) {
        Set allSkills = new HashSet();
        for (Iterator iter = user.getSkills().iterator(); iter.hasNext();) {
            Skill item = (Skill) iter.next();
            allSkills.add(item.getSkillID());
        }
        return allSkills;
    }

    /**
     * getAllRights
     *
     * @param user User
     * @return Collection
     */
    private Collection getAllRights(User user) {
        Set allRights = new HashSet();
        for (Iterator iter = user.getRights().iterator(); iter.hasNext();) {
            Right item = (Right) iter.next();
            allRights.add(item.getRightID());
        }
        for (Iterator iter = user.getRoles().iterator(); iter.hasNext();) {
            Role item = (Role) iter.next();
            for (Iterator rIter = item.getRights().iterator(); rIter.hasNext();) {
                Right rItem = (Right) rIter.next();
                allRights.add(rItem.getRightID());
            }
        }
        return allRights;
    }

}
